package services

import (
	"bytes"
	"context"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"io"
	"net/http"
	"regexp"
	"strconv"
	"strings"
	"time"
	"wecom_rebot/common"
	"wecom_rebot/core"
	"wecom_rebot/models"
)

var adCopyAccountTxLogger *logrus.Logger

// InitAdAccountCopyLogger 移除 init() 函数，改为显式初始化函数
func InitAdAccountCopyLogger() {
	// 确保在 common 初始化后调用
	adCopyAccountTxLogger = core.InitLogger(common.LogsErrorMap[10])
}

type analyzeContentResult struct {
	AccountID string
	Number    int
	Username  string
}

// AccountInfo 在 huge_ad_copy_account_service.go 中添加以下结构体
type AccountInfo struct {
	AdvName string `json:"advName"`
}

type CopyNumberResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data struct {
		MatchNum int `json:"matchNum"`
	} `json:"data"`
}

type CopyRequest struct {
	AdvId       string        `json:"advId"`
	Email       string        `json:"email"`
	CopyAdvType string        `json:"copyAdvType"`
	AdvItemList []advItemList `json:"advItemList"`
	CopySelfTag bool          `json:"copySelfTag"`
}

type advItemList struct {
	AdvName string `json:"advName"`
	Label   string `json:"label"`
}

type CopyResultList struct {
	ResultList []CopyResponse `json:"resultList"`
}

type CopyResponse struct {
	AdvId    int    `json:"advId"`
	AdvName  string `json:"advName"`
	Success  bool   `json:"success"`
	ErrorMsg struct {
		AdvName string `json:"advName"`
	} `json:"errorMsg"`
}

type HugeAdCopyAccountService struct{}

func (s *HugeAdCopyAccountService) Handle(msgId int, subjectName, roomId string, content []string, jobId uint64) error {

	var msg = &models.Msg{}

	fmt.Println("adCopyAccountTxLogger", "原始结构Id：", msgId)
	// 获取数据
	err := common.DB.Where("id = ?", msgId).First(&msg).Error
	if err != nil {
		adCopyAccountTxLogger.Error("巨量AD获取数据失败", common.LogsErrorMap[2], msgId, err)
		return err
	}

	adCopyAccountTxLogger.Info("adCopyAccountTxLogger", "原始结构：", content)

	// 处理需要的数据结构
	contentList, err := s.analyzeContent(content)
	if err != nil {
		adCopyAccountTxLogger.Error(err)
		return err
	}

	// 移除功能行
	msg.Content = RemoveTitle(msg)
	fmt.Println("adCopyAccountTxLogger", contentList, "移除后的结构：", msg, "广告主信息：", content)

	rdb := core.InitRedis(13)
	ctx := context.Background()

	cookies, err := rdb.Get(ctx, "laravel_database_oead_adv_cookies").Result()

	fmt.Println("adCopyAccountTxLogger", "Cookies:", cookies)

	// 查询任务
	var job models.Job
	if err = common.DB.Where("id = ?", jobId).First(&job).Error; err != nil {
		adCopyAccountTxLogger.Error("查询完整任务记录", common.LogsErrorMap[2], jobId, err)
		return err
	}

	// 提取并去重 AccountID
	uniqueAccount := UniqueAccountIDs(contentList)

	adCopyAccountTxLogger.Info("UniqueAccountIDs", "去重后的结构：", uniqueAccount)

	// 如果复制的是多个账号并且都是相同的账号ID
	if len(uniqueAccount) == 1 && len(contentList) != 1 {
		// 获取总共的复制数量
		totalNumber := SumNumbers(contentList)
		accountID := uniqueAccount[0]

		var oead1 models.ImportOead
		err = common.DBDk.Where("account_id = ?", accountID).Take(&oead1).Error
		if err != nil {
			adCopyAccountTxLogger.Warnf("OA不存在ID: %s", accountID)
			return errors.New("OAad不存在ID1" + err.Error())
		}

		// 检查是否存在
		exists, err := s.checkAccountExists(accountID, msg, cookies)
		if err != nil {
			adCopyAccountTxLogger.Warnf("检查账号存在失败: %v", err)
			return err
		}
		if !exists {
			return fmt.Errorf("OA不存在ID：%s", accountID)
		}

		// 获取广告主信息
		advName, err := s.getAccountInformation(accountID, msg, cookies)
		if err != nil {
			adCopyAccountTxLogger.Warnf("获取广告主信息失败: %v", err)
			return err
		}

		// 获取复制次数
		copyNumber, err := s.getCopyNumber(advName, msg, cookies)
		if err != nil {
			adCopyAccountTxLogger.Warnf("获取复制次数失败1: %v", err)
			return err
		}

		// 计算起始值
		startNumber := 1
		if copyNumber > 0 {
			startNumber = copyNumber + 1
		}
		suffixNumber := startNumber + totalNumber

		// 生成复制列表
		advItemsList := s.UniqueQuantityCalculation(accountID, advName, startNumber, suffixNumber)

		adCopyAccountTxLogger.Info("整理后的数据:", advItemsList)

		// 发送请求
		response, err := s.oeadUrlRequest(advItemsList, cookies)
		if err != nil {
			adCopyAccountTxLogger.Warnf("发送复制请求失败1: %v", err)
			return err
		}

		adCopyAccountTxLogger.Info("发送复制请求结果：", response)

		// 处理结果
		err = s.handleCopyResult(response, msg, accountID, contentList[0].Username)
		if err != nil {
			adCopyAccountTxLogger.Warnf("处理复制结果失败1: %v", err)
			return err
		}
	} else {
		// 处理多个不同账号的情况
		for _, item := range contentList {
			// 获取广告主信息
			advName, err := s.getAccountInformation(item.AccountID, msg, cookies)
			if err != nil {
				adCopyAccountTxLogger.Warnf("获取广告主信息失败: %v", err)
				return err
			}

			var oead models.ImportOead
			err = common.DBDk.Where("account_id = ?", item.AccountID).Take(&oead).Error
			if err != nil {
				adCopyAccountTxLogger.Warnf("OA不存在ID: %s", item.AccountID)
				return errors.New("OA不存在ID" + err.Error())
			}

			// 获取复制次数
			copyNumber, err := s.getCopyNumber(advName, msg, cookies)
			if err != nil {
				adCopyAccountTxLogger.Warnf("获取复制次数失败2: %v", err)
				return err
			}

			// 计算起始值
			startNumber := 1
			if copyNumber > 0 {
				startNumber = copyNumber + 1
			}

			// 生成复制列表
			advItems, err := GenerateAdvItems(item, advName, startNumber)
			if err != nil {
				adCopyAccountTxLogger.Warnf("组装账户名称失败2: %v", err)
				return err
			}

			adCopyAccountTxLogger.Info("GenerateAdvItems整理数据：", advItems)

			// 发送请求
			response, err := s.oeadUrlRequest(advItems, cookies)
			if err != nil {
				adCopyAccountTxLogger.Warnf("发送复制请求失败2: %v", err)
				return err
			}

			// 处理结果
			err = s.handleCopyResult(response, msg, item.AccountID, item.Username)
			if err != nil {
				adCopyAccountTxLogger.Warnf("处理复制结果失败2: %v", err)
				return err
			}
		}
	}
	return nil
}

// UniqueQuantityCalculation 多个账户组装账户名称
func (s *HugeAdCopyAccountService) UniqueQuantityCalculation(accountID, advName string, startNumber, suffixNumber int) []CopyRequest {
	var results []CopyRequest
	maxItems := 10
	currentStart := startNumber

	for currentStart < suffixNumber {
		// 修复后代码：
		var items []advItemList
		currentEnd := currentStart + maxItems
		if currentEnd > suffixNumber {
			currentEnd = suffixNumber
		}

		for i := currentStart; i < currentEnd; i++ {
			items = append(items, advItemList{
				AdvName: fmt.Sprintf("%s-%d", advName, i),
				Label:   fmt.Sprintf("账号名称%d", i-currentStart+1),
			})
		}

		result := CopyRequest{
			AdvId:       accountID,
			Email:       "",
			CopyAdvType: "USE_ORIGIN_ADV",
			AdvItemList: items,
			CopySelfTag: false,
		}

		results = append(results, result)
		currentStart = currentEnd
	}

	return results
}

// checkAccountExists 检查广告账户是否存在
func (s *HugeAdCopyAccountService) checkAccountExists(accountID string, msg *models.Msg, oeAdCookies string) (bool, error) {
	url := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/query/copyInfo?advId=%s", accountID)

	var response struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
		Data struct {
			AdvName string `json:"advName"`
		} `json:"data"`
	}

	err := s.SendCurlRequest(url, nil, oeAdCookies, "GET", "", &response)
	if err != nil {
		adCopyAccountTxLogger.Errorf("获取广告主信息失败: %v", err)
		return false, err
	}

	return true, nil
}

// getAccountInformation 获取广告主信息
func (s *HugeAdCopyAccountService) getAccountInformation(accountID string, msg *models.Msg, oeAdCookies string) (string, error) {
	url := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/query/copyInfo?advId=%s", accountID)

	var response struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
		Data struct {
			AdvName string `json:"advName"`
		} `json:"data"`
	}

	err := s.SendCurlRequest(url, nil, oeAdCookies, "GET", "", &response)
	if err != nil {
		adCopyAccountTxLogger.Errorf("获取广告主信息失败: %v", err)
		return "", errors.New("获取广告主信息失败1" + err.Error())
	}

	if response.Code != 0 {
		adCopyAccountTxLogger.Warnf("获取广告主信息失败: %s", response.Msg)
		return "", fmt.Errorf("获取广告主信息失败2: %s", response.Msg)
	}

	if response.Data.AdvName == "" {
		adCopyAccountTxLogger.Warn("获取广告主信息不存在")
		return "", fmt.Errorf("获取广告主信息不存在")
	}

	return response.Data.AdvName, nil
}

// getCopyNumber 获取复制次数
func (s *HugeAdCopyAccountService) getCopyNumber(accountName string, msg *models.Msg, oeAdCookies string) (int, error) {
	url := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/account/name-count?advName=%s", accountName)

	var response CopyNumberResponse
	err := s.SendCurlRequest(url, nil, oeAdCookies, "GET", "", &response)
	if err != nil {
		adCopyAccountTxLogger.Errorf("获取复制次数失败3: %v", err)
		return 0, errors.New("获取复制次数请求失败3" + err.Error())
	}

	if response.Code != 0 {
		adCopyAccountTxLogger.Warnf("获取复制次数失败4: %s", response.Msg)
		return 0, fmt.Errorf("获取复制次数失败5: %s", response.Msg)
	}

	if response.Data.MatchNum == 0 {
		adCopyAccountTxLogger.Warn("获取复制次数为空")
		return 0, fmt.Errorf("获取复制次数为空")
	}

	return response.Data.MatchNum, nil
}

// GenerateAdvItems 生成复制列表
func GenerateAdvItems(item analyzeContentResult, accountName string, startNumber int) ([]CopyRequest, error) {
	if accountName == "" {
		return nil, fmt.Errorf("广告主名称为空")
	}

	// 计算出总复制次数
	sum := startNumber + item.Number

	// 创建advItemList
	var items []advItemList

	// 从startNumber开始循环到sum
	for i := startNumber; i < sum; i++ {
		items = append(items, advItemList{
			AdvName: fmt.Sprintf("%s-%d", accountName, i),
			Label:   fmt.Sprintf("账号名称%d", i-startNumber+1),
		})
	}

	// 构建结果
	result := []CopyRequest{
		{
			AdvId:       item.AccountID,
			Email:       "",
			CopyAdvType: "USE_ORIGIN_ADV",
			AdvItemList: items,
			CopySelfTag: false,
		},
	}

	return result, nil
}

// sendCopyRequests 发送复制请求
func (s *HugeAdCopyAccountService) oeadUrlRequest(advItemList []CopyRequest, oeAdCookies string) ([]CopyResponse, error) {
	var response []CopyResponse
	count := len(advItemList)

	if count > 1 {
		for _, item := range advItemList {
			time.Sleep(2 * time.Second)
			adCopyAccountTxLogger.Info("打印所有数据：", toJSON(item))

			responses, err := s.copyOeadAccount(item, oeAdCookies)
			if err != nil {
				adCopyAccountTxLogger.Warnf("复制账户失败: %v", err)
				return nil, err
			}

			// 如果 copyOeadAccount 返回的是数组，合并到 response
			if responses != nil {
				response = append(response, responses...)
			}
		}
	} else {
		adCopyAccountTxLogger.Info("打印单条数据：", toJSON(advItemList[0]))

		responses, err := s.copyOeadAccount(advItemList[0], oeAdCookies)
		if err != nil {
			adCopyAccountTxLogger.Warnf("复制账户失败: %v", err)
			return nil, err
		}

		// 如果 copyOeadAccount 返回的是数组，合并到 response
		if responses != nil {
			response = append(response, responses...)
		}
	}

	adCopyAccountTxLogger.Info("返回的参数：", toJSON(response))

	return response, nil
}

// copyOeadAccount 复制广告账户
func (s *HugeAdCopyAccountService) copyOeadAccount(advItem CopyRequest, oeAdCookies string) ([]CopyResponse, error) {
	url := "https://agent.oceanengine.com/agent/adv-create/copy/v3"

	var personData struct {
		Code int             `json:"code"`
		Msg  string          `json:"msg"`
		Data json.RawMessage `json:"data"`
	}

	err := s.SendCurlRequest(url, advItem, oeAdCookies, "POST", "", &personData)
	if err != nil {
		adCopyAccountTxLogger.Warnf("发送复制请求失败: %v", err)
		return nil, err
	}

	adCopyAccountTxLogger.Info("复制结果:", personData)

	if personData.Code != 0 {
		adCopyAccountTxLogger.Infof("获取复制次数失败1 数据的json：%s", toJSON(personData))
		return nil, fmt.Errorf("请求返回错误码: %d, 错误信息: %s", personData.Code, personData.Msg)
	}

	var resultList CopyResultList
	err = json.Unmarshal(personData.Data, &resultList)
	if err != nil {
		adCopyAccountTxLogger.Infof("获取复制次数失败2 获取数据失败: %v", err)
		return nil, fmt.Errorf("获取数据失败: %v", err)
	}

	if len(resultList.ResultList) == 0 {
		adCopyAccountTxLogger.Infof("获取复制次数失败3 %s 数据的json：%s", personData.Msg, toJSON(personData))
		return nil, fmt.Errorf("返回结果为空")
	}

	return resultList.ResultList, nil
}

// toJSON 辅助函数：将对象转换为JSON字符串
func toJSON(v interface{}) string {
	bytes, _ := json.Marshal(v)
	return string(bytes)
}

// handleCopyResult 处理复制结果
func (s *HugeAdCopyAccountService) handleCopyResult(responses []CopyResponse, msg *models.Msg, accountID string, username string) error {
	strPj := "-----------------------------------"

	// 统计错误
	responseError := make(map[string][]string)
	responseErrorCount := 0

	// 统计正确
	var responseSuccess []string
	responseSuccessCount := 0
	var insertCopyAccount []models.CopyAccountList

	for _, value := range responses {
		adCopyAccountTxLogger.Info("循环内的参数：", toJSON(value))

		advId := strconv.Itoa(value.AdvId)

		// 检查空值
		if advId == "" && value.AdvName == "" {
			continue
		}

		if advId == "" || value.ErrorMsg.AdvName != "" {
			// 如果存在账户名称就添加到错误数组中
			if _, exists := responseError[value.ErrorMsg.AdvName]; !exists {
				responseError[value.ErrorMsg.AdvName] = []string{}
			}

			responseError[value.ErrorMsg.AdvName] = append(responseError[value.ErrorMsg.AdvName], value.AdvName)
			responseErrorCount++
		} else {
			responseSuccess = append(responseSuccess, advId)

			parentId, _ := strconv.Atoi(accountID)

			insertCopyAccount = append(insertCopyAccount, models.CopyAccountList{
				Parent:       parentId,
				AccountID:    value.AdvId,
				AccountName:  value.AdvName,
				HandleStatus: 1,
				Type:         3,
				CreatedAt:    time.Now(),
				Username:     username,
			})
			responseSuccessCount++
		}
	}

	if len(responseError) > 0 {
		var errorMessages []string

		for advName, resErr := range responseError {
			// 拼接错误信息
			errorMessage := fmt.Sprintf("%s：%s", advName, strings.Join(resErr, ","))
			errorMessages = append(errorMessages, errorMessage)
		}

		errorMessageString := strings.Join(errorMessages, "\n")
		if err := BendiSendText(
			fmt.Sprintf("%s\n%s\n复制失败数量：%d\n%s", msg.Content, strPj, responseErrorCount, errorMessageString),
			msg.RoomID,
			msg.Sender,
		); err != nil {
			adCopyAccountTxLogger.Errorf("发送消息失败1: %v", err)
		}
	}

	if len(responseSuccess) > 0 {
		// 插入数据库
		if err := common.DB.Table("copy_account_list").Create(&insertCopyAccount).Error; err != nil {
			adCopyAccountTxLogger.Errorf("数据库插入失败: %v", err)
		}

		if err := BendiSendText(
			fmt.Sprintf("%s\n%s\n复制成功数量：%d\n复制成功：%s", msg.Content, strPj, responseSuccessCount, strings.Join(responseSuccess, ",")),
			msg.RoomID,
			msg.Sender,
		); err != nil {
			adCopyAccountTxLogger.Errorf("发送消息失败2: %v", err)
		}
	}

	return nil
}

// SendCurlRequest 发送HTTP请求
func (s *HugeAdCopyAccountService) SendCurlRequest(url string, postData interface{}, xhsCookies string, method string, oeCsrfToken string, result interface{}) error {
	// 创建请求上下文
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// 序列化POST数据
	var bodyReader io.Reader
	if postData != nil {
		jsonData, err := json.Marshal(postData)
		if err != nil {
			return fmt.Errorf("JSON序列化失败: %v", err)
		}
		bodyReader = bytes.NewBuffer(jsonData)
	}

	// 创建请求
	req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
	if err != nil {
		return fmt.Errorf("创建请求失败: %v", err)
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Cookie", xhsCookies)
	if oeCsrfToken != "" {
		req.Header.Set("Cg-Csrf-Token", oeCsrfToken)
	}

	// 创建自定义客户端
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("读取响应失败: %v", err)
	}

	adCopyAccountTxLogger.Info("获取后得参数格式：", string(respBody))

	if result != nil {
		if err := json.Unmarshal(respBody, &result); err != nil {
			return fmt.Errorf("JSON解析失败: %v", err)
		}
	}
	return nil
}

// analyzeContent 解析内容为广告主信息数组
func (s *HugeAdCopyAccountService) analyzeContent(content []string) ([]analyzeContentResult, error) {
	// 初始化结果变量
	var accountIDs []string
	var copyNumber int
	var username string

	// 编译正则表达式（支持中文逗号、顿号）
	sepRegex, err := regexp.Compile(`[,，、]`)
	if err != nil {
		adCopyAccountTxLogger.Error("广告主ID分隔符正则表达式编译失败", err)
		return nil, fmt.Errorf("正则表达式编译失败: %w", err)
	}

	// 遍历内容行
	for _, line := range content {
		// 广告主ID
		if strings.HasPrefix(line, "广告主ID:") {
			raw := strings.TrimPrefix(line, "广告主ID:")
			ids := sepRegex.Split(raw, -1)
			for _, id := range ids {
				trimmed := strings.TrimSpace(id)
				if trimmed != "" {
					accountIDs = append(accountIDs, trimmed)
				}
			}
		}
		// 复制数量
		if strings.HasPrefix(line, "复制数量:") {
			strValue := strings.TrimSpace(strings.TrimPrefix(line, "复制数量:"))
			if strValue != "" {
				var err error
				copyNumber, err = strconv.Atoi(strValue)
				if err != nil {
					adCopyAccountTxLogger.Errorf("复制数量转换失败: %v", err)
					return nil, fmt.Errorf("复制数量格式错误: %w", err)
				}
			}
		}
		// 复制数量
		if strings.HasPrefix(line, "媒介名字:") {
			username = strings.TrimSpace(strings.TrimPrefix(line, "媒介名字:"))
		}
	}

	// 验证必要字段
	if len(accountIDs) == 0 {
		adCopyAccountTxLogger.Warn("未解析到有效广告主ID")
		return nil, fmt.Errorf("解析参数失败: 缺少广告账户ID")
	}

	if username == "" {
		adCopyAccountTxLogger.Warn("未解析到媒介名字")
		return nil, errors.New("解析参数失败: 缺少媒介名字")
	}

	// 构建结果
	var result []analyzeContentResult

	for _, accountId := range accountIDs {
		result = append(result, analyzeContentResult{
			AccountID: accountId,
			Number:    copyNumber,
			Username:  username,
		})
	}

	return result, nil
}

// UniqueAccountIDs 提取并去重 AccountID
func UniqueAccountIDs(contentList []analyzeContentResult) []string {
	seen := make(map[string]bool)
	var result []string

	for _, item := range contentList {
		if !seen[item.AccountID] {
			seen[item.AccountID] = true
			result = append(result, item.AccountID)
		}
	}
	return result
}

// SumNumbers 计算总复制数量
func SumNumbers(list []analyzeContentResult) int {
	total := 0
	for _, item := range list {
		total += item.Number
	}
	return total
}
